package com.jk.vehicle.mini.controller;

import com.alibaba.excel.util.CollectionUtils;
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.baomidou.dynamic.datasource.provider.DynamicDataSourceProvider;
import com.jk.vehicle.mini.constant.SellStatusEnum;
import com.jk.vehicle.mini.constant.UserTypeEnum;
import com.jk.vehicle.mini.dto.LinkUserAndBicycleDTO;
import com.jk.vehicle.mini.entity.*;
import com.jk.vehicle.mini.service.*;
import com.jk.vehicle.mini.util.BeanMapperUtil;
import com.jk.vehicle.mini.util.RedisUtil;
import com.jk.vehicle.mini.util.SequenceUtils;
import com.jk.vehicle.mini.util.SpringContextUtils;
import com.jk.vehicle.mini.vo.*;
import com.jk.vehicle.core.controller.BaseController;
import com.jk.vehicle.core.entity.ResponseEntity;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import tk.mybatis.mapper.entity.Condition;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

@Api(value = "车辆相关接口", tags = "车辆相关接口")
@Slf4j
@RestController
@RequestMapping("/bicycle")
public class BicycleController extends BaseController {
    @Resource
    private ElectricBicycleService electricBicycleService;

    @Resource
    private UserBicycleLinkService userBicycleLinkService;

    @Resource
    private UserBicycleCorpService userBicycleCorpService;

    @Resource
    private ProductService productService;

    @Resource
    private CorpService corpService;

    @Resource
    private OrderService orderService;

    @Resource
    private UserService userService;

    @Resource
    private RedisUtil redisUtil;

    /**
     * 分享码过期时间，1天
     */
    private final static Long SHARE_EXPIRE_TIME = 86400L;

    /**
     * 根据扫码获取数据查询对应的车辆√
     */
    @ApiOperation("根据扫码获取数据查询对应的车辆")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "qrData", value = "扫码获得的序列号数据"),
            @ApiImplicitParam(name = "corpId", value = "厂家ID")
    })
    @GetMapping("/scan_bicycle_data")
    public ResponseEntity<ScanBicycleVO> scanBicycleData(String qrData, Long corpId){
        if (corpId == null || corpId.longValue() == 0) {
            return failResult("厂家id不能为空！");
        }
        if (corpId == -1) {
            return failResult("厂家id不能等于-1");
        }
        String dsName = corpService.selectDsNameById(corpId);
        if (StringUtils.isBlank(qrData)){
            return failResult("缺少必要参数！");
        }
        // 首先查询车辆信息
        Condition condition = new Condition(ElectricBicycle.class);
        condition.createCriteria().andEqualTo("code", qrData);
        List<ElectricBicycle> electricBicycleList = electricBicycleService.findByCondition(condition, dsName);
        if (CollectionUtils.isEmpty(electricBicycleList)){
            return failResult("此车辆数据不存在");
        }
        ElectricBicycle electricBicycle = electricBicycleList.get(0);
        // 查询车辆对应的厂家id、产品id数据
        List<BicycleLinkIdVO> bicycleLinkIdVOList = electricBicycleService.queryBicycleLinkId(electricBicycle.getId(), dsName);
        if (CollectionUtils.isEmpty(bicycleLinkIdVOList)){
            return failResult("车辆数据异常，对应的产品或者厂家数据为空");
        }
        // 查询车辆关联的厂家id、商品id
        BicycleLinkIdVO bicycleLinkIdVO = bicycleLinkIdVOList.get(0);
        /**
         * corpService.findById(corpId,null).getMini_status()
         * 通过厂家ID直接获取 厂家对象
         * 设置该车辆的厂家是否使用通用小程序
         */
        ScanBicycleVO scanBicycleVO = new ScanBicycleVO(bicycleLinkIdVO.getProdId(), bicycleLinkIdVO.getCorpId(),corpService.findById(corpId,null).getMini_status());
        BeanMapperUtil.convert(electricBicycle, scanBicycleVO);
        return successResult(scanBicycleVO);
    }

    /**
     * 创建人员和车辆联系（扫码之后）√
     */
    @ApiOperation("创建人员和车辆联系（扫码之后）")
    @PostMapping("/link_user_and_bicycle")
    public ResponseEntity linkUserAndBicycle(@Valid @RequestBody LinkUserAndBicycleDTO linkUserAndBicycleDTO, BindingResult bindingResult){
        if (linkUserAndBicycleDTO.getCorpId().longValue() == 0 || linkUserAndBicycleDTO.getCorpId() == null) {
            return failResult("厂家id不能为空！");
        }
        if (linkUserAndBicycleDTO.getCorpId() == -1) {
            return failResult("厂家id不能等于-1");
        }
        User user = userService.findById(linkUserAndBicycleDTO.getUserId(), null);
        if (user == null) {
            return failResult("该用户不存在！");
        }
        List<String> dsNameList = new ArrayList<>();
        String dsName = corpService.selectDsNameById(linkUserAndBicycleDTO.getCorpId());
        //新增用户信息
        User userObj = userService.findById(linkUserAndBicycleDTO.getUserId(), dsName);
        if (userObj == null) {
            user.setCreateDate(new Date());
            user.setUpdateDate(null);
            userService.save(user, dsName);
        }
        dsNameList.add(null);//null：代表通用数据源，非空代表独立数据源
        dsNameList.add(dsName);
        checkBindingResult(bindingResult);
        // 首先查询车辆是否已经被绑定
        Condition condition = new Condition(UserBicycleLink.class);
        condition.createCriteria().andEqualTo("bicycleId", linkUserAndBicycleDTO.getBicycleId())
                .andEqualTo("userType", UserTypeEnum.MANAGER.getCode());
        List<UserBicycleLink> userBicycleLinkList = userBicycleLinkService.findByCondition(condition, dsName);
        if (!CollectionUtils.isEmpty(userBicycleLinkList)){
            return failResult("该车辆已经被绑定，无法再次绑定！");
        }
        // 修改车辆信息，如果车辆未售出，则更新售出状态和时间
        ElectricBicycle electricBicycle = electricBicycleService.findById(linkUserAndBicycleDTO.getBicycleId(), dsName);
        if (electricBicycle == null){
            return failResult("待绑定车辆信息不存在！");
        }
        // 待出货不允许扫码绑定
        if (SellStatusEnum.WAIT_SALE.getCode().equals(electricBicycle.getSellStatus())) {
            return failResult("该车辆状态无法绑定！");
        }
        // 修改车辆的名称
        electricBicycle.setName(linkUserAndBicycleDTO.getBicycleName());
        // 如果该车辆正在出售，则更新出售状态，并更新出售时间
        if (SellStatusEnum.NO_SALE.getCode().equals(electricBicycle.getSellStatus()) || SellStatusEnum.ON_SALE.getCode().equals(electricBicycle.getSellStatus())){
            electricBicycle.setSellStatus(SellStatusEnum.SOLD_OUT.getCode());
            System.out.println("当前系统时间="+new Date());
            electricBicycle.setSellDate(new Date());
        }
        electricBicycleService.update(electricBicycle, dsName);
        // 建立人员和车辆关联关系
        UserBicycleLink userBicycleLink = UserBicycleLink.UserBicycleLinkBuilder.anUserBicycleLink()
                .withId(SequenceUtils.nextId())
                .withUserType(UserTypeEnum.MANAGER.getCode())
                .withUserId(linkUserAndBicycleDTO.getUserId())
                .withProdId(linkUserAndBicycleDTO.getProdId())
                .withCorpId(linkUserAndBicycleDTO.getCorpId())
                .withBicycleId(linkUserAndBicycleDTO.getBicycleId())
                .withBuyDate(linkUserAndBicycleDTO.getBuyDate())
                .withCreateDate(new Date())
                .build();
        for (String dbName: dsNameList) {
            userBicycleLinkService.save(userBicycleLink, dbName);
        }
        NetAndProdDetailsVo netAndProdDetailsVo = orderService.selectNetAndProdDetailsById(linkUserAndBicycleDTO.getBicycleId(), dsName);
        if (netAndProdDetailsVo != null) {
            // 生成订单
            Order order = new Order();
            order.setArea(netAndProdDetailsVo.getArea());
            order.setDealer(netAndProdDetailsVo.getDealer());
            order.setSeries(netAndProdDetailsVo.getSeries());
            order.setModel(netAndProdDetailsVo.getModel());
            order.setSerialNumber(netAndProdDetailsVo.getSerialNumber());
            order.setUserId(linkUserAndBicycleDTO.getUserId());
            order.setCorpId(linkUserAndBicycleDTO.getCorpId());
            order.setCreateUser(linkUserAndBicycleDTO.getUserId());
            order.setUpdateUser(linkUserAndBicycleDTO.getUserId());
            order.setUpdateDate(new Date());
            orderService.save(order, dsName);
        }
        return successResult();
    }


    /**
     * 生成车辆分享码（发送分享链接）
     */
    @ApiOperation("生成车辆分享码（发送分享链接）")
    @ApiImplicitParam(name = "bicycleId", value = "车辆id")
    @GetMapping("/find_share_code")
    public ResponseEntity<String> findShareCode(Long bicycleId){
        String shareCode = UUID.randomUUID().toString().replace("-", "");
        // redis缓存格式为 分享码：车辆id
        redisUtil.set(shareCode, bicycleId, SHARE_EXPIRE_TIME);
        return successResult(shareCode);
    }

    /**
     * 查询用户关联的车辆信息列表（首页）√
     * @param userId 用户ID
     * @return 结果
     */
    @ApiOperation("查询用户关联的车辆信息列表（首页）")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户主键ID"),
            @ApiImplicitParam(name = "corpId", value = "厂家ID")
    })
    @GetMapping("/query_bicycle_of_user")
    public ResponseEntity<List<BicycleOfUserVO>> queryBicycleOfUser(Long userId, Long corpId){
        if (corpId == null || corpId.longValue() == 0) {
            return failResult("厂家id不能为空！");
        }
        User user = userService.findById(userId, null);
        if (user == null) {
            return failResult("该用户不存在！");
        }
        List<BicycleOfUserVO> bicycleOfUserVOList = new ArrayList<>();
        if (corpId == -1) {
            //用户绑定车辆之后才能切换数据源查询车辆列表避免切换不必要的数据源
            List<UserBicycleLink> userBicycleLinkList = userBicycleLinkService.queryUserBicycleLinkCommonCorpById(user.getId());
            if (!CollectionUtils.isEmpty(userBicycleLinkList)) {
                for (UserBicycleLink userBicycleLink : userBicycleLinkList) {
                    String dsName = corpService.selectDsNameById(userBicycleLink.getCorpId());
                    bicycleOfUserVOList.addAll(electricBicycleService.queryBicycleOfUser(userId, dsName));
                }
            }
        } else {
            String dsName = corpService.selectDsNameById(corpId);
            bicycleOfUserVOList.addAll(electricBicycleService.queryBicycleOfUser(userId, dsName));
        }
        return successResult(bicycleOfUserVOList);
    }

    /**
     * 查询用户关联的车辆信息列表（我的车辆页面）√
     */
    @ApiOperation("查询用户关联的车辆信息列表（我的车辆页面）")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户ID"),
            @ApiImplicitParam(name = "corpId", value = "厂家ID")
    })
    @GetMapping("/query_bicycle_detail_of_user")
    public ResponseEntity<List<BicycleDetailOfUserVO>> queryBicycleDetailOfUser(Long userId, Long corpId){
        if (corpId == null || corpId.longValue() == 0) {
            return failResult("厂家id不能为空！");
        }
        User user = userService.findById(userId, null);
        if (user == null) {
            return failResult("该用户不存在！");
        }
        List<BicycleDetailOfUserVO> bicycleDetailOfUserVOList = new ArrayList<>();
        if (corpId == -1) {
            //用户绑定车辆之后才能切换数据源查询车辆列表避免切换不必要的数据源
            List<UserBicycleLink> userBicycleLinkList = userBicycleLinkService.queryUserBicycleLinkCommonCorpById(user.getId());
            if (!CollectionUtils.isEmpty(userBicycleLinkList)) {
                for (UserBicycleLink userBicycleLink : userBicycleLinkList) {
                    String dsName = corpService.selectDsNameById(userBicycleLink.getCorpId());
                    bicycleDetailOfUserVOList.addAll(electricBicycleService.queryBicycleDetailOfUser(userId, userBicycleLink.getCorpId(), dsName));
                }
            }
        } else {
            String dsName = corpService.selectDsNameById(corpId);
            bicycleDetailOfUserVOList.addAll(electricBicycleService.queryBicycleDetailOfUser(userId, corpId, dsName));
        }
        return successResult(bicycleDetailOfUserVOList);
    }

    /**
     * 查询车辆详情（车辆详情页）√
     */
    @ApiOperation("查询车辆详情（车辆详情页）")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "bicycleId", value = "车辆ID"),
            @ApiImplicitParam(name = "userId", value = "登录用户ID"),
            @ApiImplicitParam(name = "corpId", value = "厂家ID")
    })
    @GetMapping("/find_bicycle_detail")
    public ResponseEntity<BicycleDetailVO> findBicycleDetail(Long bicycleId, Long userId, Long corpId){

        if (corpId == null || corpId.longValue() == 0) {
            return failResult("厂家id不能为空！");
        }
        if (corpId == -1) {
            return failResult("厂家id不能等于-1！");
        }
        String dsName = corpService.selectDsNameById(corpId);
        if (bicycleId == null){
            return failResult("缺少必要参数！");
        }
        // 查询车辆基本数据
        ElectricBicycle electricBicycle = electricBicycleService.findById(bicycleId, dsName);
        System.out.println("查询车辆基本数据electricBicycle = " + electricBicycle.toString());
        if (electricBicycle == null) {
            return failResult("待查询车辆详情不存在！");
        }
        // 查询中间表数据
        Condition condition = new Condition(UserBicycleLink.class);
        condition.createCriteria().andEqualTo("userId", userId)
                .andEqualTo("bicycleId", bicycleId)
                .andEqualTo("userType", UserTypeEnum.MANAGER.getCode());
        List<UserBicycleLink> userBicycleLinkList = userBicycleLinkService.findByCondition(condition, dsName);
        if (CollectionUtils.isEmpty(userBicycleLinkList)){
            return failResult("详情查询异常！车辆和当前登录用户关联数据不存在！");
        };
        UserBicycleLink userBicycleLink = userBicycleLinkList.get(0);
        // 查询车辆商品数据
        Product product = productService.findById(corpId, dsName);
        if (product == null) {
            return failResult("详情查询异常！车辆所属商品信息不存在！");
        }
//        log.info("进行时2");
        // 查询车辆厂家数据
        System.out.println("ID:"+electricBicycle.getProdId());
        System.out.println("corpId = " + corpId);
        Corp corp = corpService.findById(electricBicycle.getCorpId(), dsName);
//        log.info("进行时3");
        if (corp == null){
            return failResult("详情查询异常！车辆所属厂家信息不存在！");
        }

        // 查询车辆的分享数据
        List<UserBicycleLinkVO> userBicycleLinkVOList = userBicycleLinkService.queryShareLinkData(bicycleId, dsName);
        // 组装待返回数据
        BicycleDetailVO bicycleDetailVO = BicycleDetailVO.BicycleDetailVOBuilder.aBicycleDetailVO()
                .withBuyDate(userBicycleLink.getBuyDate())
                .withCode(electricBicycle.getCode())
                .withCorpName(corp.getName())
                .withMac(electricBicycle.getMac())
                .withImgs(product.getImgs())
                .withImgUris(product.getImgUris())
                .withName(electricBicycle.getName())
                .withProdName(product.getName())
                .withUserBicycleLinkList(userBicycleLinkVOList)
                .build();
        return successResult(bicycleDetailVO);
    }

    /**
     * 删除用户所管理的车辆（车辆详情删除按钮）√
     */
    @ApiOperation("删除用户所管理的车辆（车辆详情删除按钮）")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "bicycleId", value = "车辆ID"),
            @ApiImplicitParam(name = "corpId", value = "厂家ID")
    })
    @GetMapping("/remove_bicycle")
    public ResponseEntity removeBicycleOfUser(Long bicycleId, Long corpId){
        if (corpId == null || corpId.longValue() == 0) {
            return failResult("厂家id不能为空！");
        }
        if (corpId == -1) {
            return failResult("厂家id不能等于-1！");
        }
        if (bicycleId == null){
            return failResult("缺少必要参数");
        }
        List<String> dsNameList = new ArrayList<>();
        String dsName = corpService.selectDsNameById(corpId);
        dsNameList.add(null);//null：代表通用数据源
        dsNameList.add(dsName);
        // 删除车辆在关联表中的所有关联信息，包括管理员和被分享的人员
        Condition condition = new Condition(UserBicycleLink.class);
        condition.createCriteria().andEqualTo("bicycleId", bicycleId);
        // 删除独立数据源的同时删除通用数据源
        for (String dbName: dsNameList) {
            userBicycleLinkService.deleteByCondition(condition, dbName);
        }
        return successResult();
    }

    /**
     * 关联分享车辆的信息√
     * @param shareCode 企业邀请码
     * @param userId 用户id
     * @param limitDate 分享到期时间
     */
    @ApiOperation("关联分享车辆的信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "shareCode", value = "企业邀请码"),
            @ApiImplicitParam(name = "userId", value = "用户id"),
            @ApiImplicitParam(name = "corpId", value = "厂家id"),
            @ApiImplicitParam(name = "limitDate", value = "用户小程序openId")
    })
    @PostMapping("/linkBicycle")
    private ResponseEntity<UserBicycleLink> linkBicycle(String shareCode, Long userId, Long corpId, Date limitDate){
        if (corpId == null || corpId.longValue() == 0) {
            return failResult("厂家id不能为空！");
        }
        if (corpId == -1) {
            return failResult("厂家id不能等于-1！");
        }
        User user = userService.findById(userId, null);
        if (user == null) {
            return failResult("该用户不存在！");
        }
        List<String> dsNameList = new ArrayList<>();
        String dsName = corpService.selectDsNameById(corpId);
        dsNameList.add(null);
        dsNameList.add(dsName);
        // 如果分享链接不存在，则不做任何处理
        if (redisUtil.get(shareCode) == null){
            return failResult("车辆分享链接已失效！");
        }
        // 获取车辆id
        Long bicycleId = Long.parseLong(redisUtil.get(shareCode).toString());
        // 首先查询人员是否是车辆的管理员，如果是则不做处理，否则先删除用户关联，后重新建立关联
        Condition condition = new Condition(UserBicycleLink.class);
        condition.createCriteria().andEqualTo("bicycleId", bicycleId)
                .andEqualTo("userId", userId)
                .andEqualTo("userType", UserTypeEnum.MANAGER.getCode());
        List<UserBicycleLink> userBicycleLinkList = userBicycleLinkService.findByCondition(condition, dsName);
        // 被分享用户不是管理员时，进行分享车辆的关联
        if (userBicycleLinkList.isEmpty()){
            // 首先删除用户和当前车辆的关联
            condition.clear();
            condition.createCriteria().andEqualTo("bicycleId", bicycleId)
                    .andEqualTo("userId", userId);
            for (String dbName: dsNameList) {
                userBicycleLinkService.deleteByCondition(condition, dbName);
            }
            // 新增用户和车辆的关联
            List<BicycleLinkIdVO> bicycleLinkIdVOList = electricBicycleService.queryBicycleLinkId(bicycleId, dsName);
            if (!CollectionUtils.isEmpty(bicycleLinkIdVOList)){
                BicycleLinkIdVO bicycleLinkIdVO = bicycleLinkIdVOList.get(0);
                // 查询车辆管理员，只有一个管理员
                condition.clear();
                condition.createCriteria().andEqualTo("bicycleId", bicycleId)
                        .andEqualTo("userType", UserTypeEnum.MANAGER.getCode());
                List<UserBicycleLink> userBicycleLinkListOne = userBicycleLinkService.findByCondition(condition, dsName);
                // 查询分享来源人
                Long shareFromUser = null;
                if (!CollectionUtils.isEmpty(userBicycleLinkListOne)){
                    shareFromUser = userBicycleLinkListOne.get(0).getUserId();
                }
                // 进行中间表关联
                UserBicycleLink userBicycleLink = UserBicycleLink.UserBicycleLinkBuilder.anUserBicycleLink()
                        .withId(SequenceUtils.nextId())
                        .withBicycleId(bicycleId)
                        .withCorpId(bicycleLinkIdVO.getCorpId())
                        .withProdId(bicycleLinkIdVO.getProdId())
                        .withShareLimitDate(limitDate)
                        .withShareFromUser(shareFromUser)
                        .withUserId(userId)
                        .withUserType(UserTypeEnum.NORMAL.getCode())
                        .withCreateDate(new Date())
                        .build();
                for (String dbName: dsNameList) {
                    userBicycleLinkService.save(userBicycleLink, dbName);
                }
            }
        }
        // 关联之后，使分享码立即失效
        redisUtil.remove(shareCode);
        return successResult();
    }

}